﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using WPF.Common;

namespace TB4
{
    [TemplatePart(Name = "PART_GroupSelector", Type = typeof(Selector))]
    public class TheRealGroupToolBar : ToolBar
    {

        private List<Selector> _groups;
        private Selector _selectedGroup;


        static TheRealGroupToolBar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TheRealGroupToolBar), new FrameworkPropertyMetadata(typeof(TheRealGroupToolBar)));
        }


        public TheRealGroupToolBar()
        {
            Loaded += OnLoaded;
        }

        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            if (!IsGrouping)
                return;

            _groups = this.GetDescendants2<Selector>();
            foreach (var selector in _groups)
            {
                selector.IsKeyboardFocusWithinChanged += SelectorOnIsKeyboardFocusWithinChanged;
            }
        }

        private void SelectorOnIsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            if ((bool)dependencyPropertyChangedEventArgs.NewValue)
            {
                _selectedGroup = (Selector)sender;

                var b = new Binding("SelectedItem") { Source = this, Mode = BindingMode.TwoWay };

                _selectedGroup.SetBinding(Selector.SelectedItemProperty, b);

                SelectedItem = _selectedGroup.SelectedItem;
            }
        }

        #region SelectedItem

        /// <summary>
        /// SelectedItem Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemChanged)));

        /// <summary>
        /// Gets or sets the SelectedItem property. This dependency property 
        /// indicates ....
        /// </summary>
        public object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        /// <summary>
        /// Handles changes to the SelectedItem property.
        /// </summary>
        private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TheRealGroupToolBar target = (TheRealGroupToolBar)d;
            object oldSelectedItem = (object)e.OldValue;
            object newSelectedItem = target.SelectedItem;
            target.OnSelectedItemChanged(oldSelectedItem, newSelectedItem);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the SelectedItem property.
        /// </summary>
        protected virtual void OnSelectedItemChanged(object oldSelectedItem, object newSelectedItem)
        {
        }

        #endregion

        #region DefaultGroupStyle

        /// <summary>
        /// DefaultGroupStyle Dependency Property
        /// </summary>
        public static readonly DependencyProperty DefaultGroupStyleProperty =
            DependencyProperty.Register("DefaultGroupStyle", typeof(GroupStyle), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata((GroupStyle)null,
                    new PropertyChangedCallback(OnDefaultGroupStyleChanged)));

        /// <summary>
        /// Gets or sets the DefaultGroupStyle property. This dependency property 
        /// indicates ....
        /// </summary>
        public GroupStyle DefaultGroupStyle
        {
            get { return (GroupStyle)GetValue(DefaultGroupStyleProperty); }
            set { SetValue(DefaultGroupStyleProperty, value); }
        }

        /// <summary>
        /// Handles changes to the DefaultGroupStyle property.
        /// </summary>
        private static void OnDefaultGroupStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var target = (TheRealGroupToolBar)d;
            var oldDefaultGroupStyle = (GroupStyle)e.OldValue;
            var newDefaultGroupStyle = target.DefaultGroupStyle;
            target.OnDefaultGroupStyleChanged(oldDefaultGroupStyle, newDefaultGroupStyle);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the DefaultGroupStyle property.
        /// </summary>
        protected virtual void OnDefaultGroupStyleChanged(GroupStyle oldDefaultGroupStyle, GroupStyle newDefaultGroupStyle)
        {
            if (newDefaultGroupStyle == null)
            {
                return;
            }

            if (GroupStyle.Count == 0)
            {
                GroupStyle.Add(newDefaultGroupStyle);
            }
        }

        #endregion

        #region NoGroupsItemTemplate

        /// <summary>
        /// NoGroupsItemTemplate Dependency Property
        /// </summary>
        public static readonly DependencyProperty NoGroupsItemTemplateProperty =
            DependencyProperty.Register("NoGroupsItemTemplate", typeof(DataTemplate), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata((DataTemplate)null,
                    new PropertyChangedCallback(OnNoGroupsItemTemplateChanged)));

        /// <summary>
        /// Gets or sets the NoGroupsItemTemplate property. This dependency property 
        /// indicates ....
        /// </summary>
        public DataTemplate NoGroupsItemTemplate
        {
            get { return (DataTemplate)GetValue(NoGroupsItemTemplateProperty); }
            set { SetValue(NoGroupsItemTemplateProperty, value); }
        }

        /// <summary>
        /// Handles changes to the NoGroupsItemTemplate property.
        /// </summary>
        private static void OnNoGroupsItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TheRealGroupToolBar target = (TheRealGroupToolBar)d;
            DataTemplate oldNoGroupsItemTemplate = (DataTemplate)e.OldValue;
            DataTemplate newNoGroupsItemTemplate = target.NoGroupsItemTemplate;
            target.OnNoGroupsItemTemplateChanged(oldNoGroupsItemTemplate, newNoGroupsItemTemplate);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the NoGroupsItemTemplate property.
        /// </summary>
        protected virtual void OnNoGroupsItemTemplateChanged(DataTemplate oldNoGroupsItemTemplate, DataTemplate newNoGroupsItemTemplate)
        {
        }

        #endregion
        
        #region ToolbarItemTemplate

        /// <summary>
        /// ToolbarItemTemplate Dependency Property
        /// </summary>
        public static readonly DependencyProperty ToolbarItemTemplateProperty =
            DependencyProperty.Register("ToolbarItemTemplate", typeof(DataTemplate), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata((DataTemplate)null));

        /// <summary>
        /// Gets or sets the ToolbarItemTemplate property. This dependency property 
        /// indicates ....
        /// </summary>
        public DataTemplate ToolbarItemTemplate
        {
            get { return (DataTemplate)GetValue(ToolbarItemTemplateProperty); }
            set { SetValue(ToolbarItemTemplateProperty, value); }
        }

        #endregion

        #region SelectorContextMenuItemTemplate

        /// <summary>
        /// SelectorContextMenuItemTemplate Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectorContextMenuItemTemplateProperty =
            DependencyProperty.Register("SelectorContextMenuItemTemplate", typeof(DataTemplate), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata((DataTemplate)null));

        /// <summary>
        /// Gets or sets the SelectorContextMenuItemTemplate property. This dependency property 
        /// indicates ....
        /// </summary>
        public DataTemplate SelectorContextMenuItemTemplate
        {
            get { return (DataTemplate)GetValue(SelectorContextMenuItemTemplateProperty); }
            set { SetValue(SelectorContextMenuItemTemplateProperty, value); }
        }

        #endregion

        #region SelectorContextMenuItemContainerStyle

        /// <summary>
        /// SelectorContextMenuItemContainerStyle Dependency Property
        /// </summary>
        public static readonly DependencyProperty SelectorContextMenuItemContainerStyleProperty =
            DependencyProperty.Register("SelectorContextMenuItemContainerStyle", typeof(Style), typeof(TheRealGroupToolBar),
                new FrameworkPropertyMetadata((Style)null));

        /// <summary>
        /// Gets or sets the SelectorContextMenuItemContainerStyle property. This dependency property 
        /// indicates ....
        /// </summary>
        public Style SelectorContextMenuItemContainerStyle
        {
            get { return (Style)GetValue(SelectorContextMenuItemContainerStyleProperty); }
            set { SetValue(SelectorContextMenuItemContainerStyleProperty, value); }
        }

        #endregion

    }
}